<script lang="ts" context="module">
  let id = 0;

  function getId() {
    id += 1;
    return id;
  }
</script>

<script lang="ts">
  import { createEventDispatcher } from 'svelte';

  import TabComponent from './Tab.svelte';
  import type { Tab, TabEvents } from './TabContainerTypes';

  const dispatch = createEventDispatcher<TabEvents>();
  const componentId = getId();

  export let tabs: Tab[] = [];
  export let activeTab: Tab | undefined = tabs[0];
  export let idKey = 'id';
  export let labelKey = 'label';
  export let linkKey = 'href';
  export let preventDefault = false;
  export let fillTabWidth = false;
  export let fillContainerHeight = false;
  export let uniformTabWidth = true;
  export let tabStyle: 'default' | 'compact' = 'default';
  export let hideTabsInCaseOfSingleTab = false;

  $: hideTabs = hideTabsInCaseOfSingleTab && tabs.length === 1;

  function selectActiveTab(e: Event, tab: Tab) {
    const hasLink = !!tab[linkKey];
    if (!hasLink) {
      activeTab = tab;
    }
    dispatch('tabSelected', {
      tab,
      originalEvent: e,
    });
  }

  function focusTab(e: Event) {
    // @ts-ignore: https://github.com/centerofci/mathesar/issues/1055
    (e.target as Node).parentElement.classList.add('focused');
  }

  function blurTab(e: Event) {
    // @ts-ignore: https://github.com/centerofci/mathesar/issues/1055
    (e.target as Node).parentElement.classList.remove('focused');
  }

  function checkAndPreventDefault(e: Event) {
    if (preventDefault) {
      e.preventDefault();
      const tab = (e.target as HTMLElement).closest('a[role="tab"]');
      (tab as HTMLElement)?.focus?.();
    }
  }

  function getTabLink(tab: Tab) {
    return tab[linkKey] as string | undefined;
  }
</script>

<div
  class="tab-container"
  role="navigation"
  class:fill-container-height={fillContainerHeight}
  class:compact={tabStyle === 'compact'}
>
  {#if !hideTabs}
    <ul role="tablist" class="tabs" class:fill-tab-width={fillTabWidth}>
      {#each tabs as tab (tab[idKey] || tab)}
        <TabComponent
          {componentId}
          {tab}
          {uniformTabWidth}
          link={getTabLink(tab)}
          totalTabs={tabs.length}
          isActive={tab[idKey] === activeTab?.[idKey]}
          on:focus={focusTab}
          on:blur={blurTab}
          on:click={checkAndPreventDefault}
          on:mousedown={(e) => selectActiveTab(e, tab)}
        >
          <slot name="tab" {tab}>
            {tab[labelKey]}
          </slot>
        </TabComponent>
      {/each}
    </ul>
  {/if}

  <div class="tab-content-holder">
    <div
      role="tabpanel"
      aria-hidden="false"
      id="mtsr-{componentId}-tabpanel"
      aria-labelledby="mtsr-{componentId}-tab"
      tabindex="0"
    >
      {#if activeTab}
        <slot {activeTab} />
      {/if}
    </div>
  </div>
</div>
